home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 November: Tool Chest / Dev.CD Nov 96 TC / Dev.CD Nov 96 TC.toast / Sample Code / Interapplication Communication / MenuScripter 4.0 / Sources / MSAESelect.c < prev    next >
Encoding:
Text File  |  1996-07-09  |  7.0 KB  |  285 lines  |  [TEXT/CWIE]

  1. // MSAESelect.c
  2. //
  3. // Original version by Jon Lansdell and Nigel Humphreys.
  4. // 4.0 and 3.1 updates by Greg Sutton.
  5. // ©Apple Computer Inc 1996, all rights reserved.
  6.  
  7. #include "MSAESelect.h"
  8.  
  9. #include <Windows.h>
  10.  
  11. #include "MSAEUtils.h"
  12. #include "MSWindow.h"        // for DPtrFromWindowPtr()
  13.  
  14. #include "MSAETextUtils.h"
  15. #include "MSAEWindowUtils.h"
  16. #include "MSMain.h"
  17.  
  18. // -----------------------------------------------------------------------
  19. //    Name:         DoSelect
  20. //    Purpose:    Handles the 'Select' Apple Event, extracting the direct
  21. //                object (which is the text range to set the selection to) 
  22. //                'Select' is equivalent to 'set the selection to...'
  23. // -----------------------------------------------------------------------
  24.      
  25. pascal OSErr    DoSelect(const AppleEvent *theAppleEvent, AppleEvent *reply, long refcon)
  26. {
  27. #ifdef __MWERKS__
  28.     #pragma unused (refcon)
  29. #endif
  30.  
  31.     AEDesc        directObj = {typeNull, NULL},
  32.                 result = {typeNull, NULL};
  33.     OSErr        err;
  34.  
  35.     err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObj);
  36.     
  37.             // There was a direct parameter
  38.     if (directObj.descriptorType != typeNull)
  39.         err = SelectDesc(&directObj, &result);
  40.     else    // There was no direct parameter
  41.     {
  42.         err = PutPStringToDescriptor(&result, "\pYou have not specified an object to select");
  43.         if (noErr != err) goto done;
  44.         err = errAENoSuchObject;
  45.     }
  46.  
  47.     err = AddResultToReply(&result, reply, err);
  48.  
  49. done:    
  50.     (void)AEDisposeDesc(&directObj);
  51.     (void)AEDisposeDesc(&result);
  52.         
  53.     return(err);
  54. } // DoSelect
  55.  
  56.  
  57. OSErr    SelectWindowToken(WindowToken* theToken)
  58. {
  59.     OSErr            err = noErr;
  60.     
  61.     if (! theToken->tokenWindow)
  62.         return errAENoSuchObject;
  63.         
  64.     SelectWindow( theToken->tokenWindow );
  65.     if ( IsVisible( theToken->tokenWindow ) )
  66.     {
  67.         DoActivate( GetNthWindow( 2 ), false );
  68.         DoActivate( theToken->tokenWindow, true );
  69.     }
  70.  
  71.                                     
  72.     return(err);
  73. }
  74.  
  75. OSErr    SelectWindowDesc(AEDesc* windowDesc)
  76. {
  77.     AEDesc            aDesc = { typeNull, NULL };
  78.     WindowToken        aToken;
  79.     Size            actualSize;
  80.     OSErr            err;
  81.  
  82.     err = AECoerceDesc( windowDesc, typeMyWndw, &aDesc );
  83.     if ( noErr != err ) goto done;
  84.         
  85.     GetRawDataFromDescriptor( &aDesc, (Ptr)&aToken, sizeof( aToken ), &actualSize );
  86.  
  87.     err = SelectWindowToken( &aToken );
  88.  
  89. done:
  90.     (void)AEDisposeDesc( &aDesc );
  91.     
  92.     return(err);
  93. }
  94.  
  95.  
  96. OSErr    SelectTextToken(TextToken* theToken)
  97. {
  98.     DPtr            docPtr;
  99.     OSErr            err = noErr;
  100.     
  101.     docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
  102.     
  103.     if (! theToken->tokenWindow || ! docPtr)
  104.         return errAEWrongDataType;
  105.     
  106.     TESetSelect(theToken->tokenOffset - 1,
  107.                     theToken->tokenOffset + theToken->tokenLength - 1,
  108.                                     docPtr->theText);
  109.                                     
  110.     return(err);
  111. }
  112.  
  113. OSErr    SelectTextDesc(AEDesc* textDesc)
  114. {
  115.     TextToken        aTextToken;
  116.     Size            actualSize;
  117.     OSErr            err;
  118.  
  119.     if (typeMyText != textDesc->descriptorType)
  120.         return(errAETypeError);
  121.         
  122.     GetRawDataFromDescriptor(textDesc, (Ptr)&aTextToken, sizeof(aTextToken), &actualSize);
  123.  
  124.     err = SelectTextToken(&aTextToken);
  125.     
  126.     return(err);
  127. }
  128.  
  129.  
  130. OSErr    SelectMenuItemToken( MenuItemToken* theToken )
  131. {
  132.     OSErr            err = noErr;
  133.         
  134.     DoMenuItem( theToken->tokenMenuToken.tokenID, theToken->tokenItem );
  135.                                     
  136.     return err;
  137. }
  138.  
  139. OSErr    SelectMenuItemDesc( AEDesc* theDesc )
  140. {
  141.     MenuItemToken    aToken;
  142.     Size            actualSize;
  143.     OSErr            err;
  144.  
  145.     if ( typeMyMenuItem != theDesc->descriptorType )
  146.         return errAETypeError;
  147.         
  148.     GetRawDataFromDescriptor( theDesc, (Ptr)&aToken, sizeof( aToken ), &actualSize );
  149.  
  150.     err = SelectMenuItemToken( &aToken );
  151.     
  152.     return err;
  153. }
  154.  
  155.  
  156. OSErr    SelectDesc( const AEDesc* aDesc, AEDesc* result )
  157. {
  158.     AEDesc        selectDesc = {typeNull, NULL},
  159.                 textDesc = {typeNull, NULL};
  160.     OSErr        err;
  161.     
  162.     if ( typeObjectSpecifier == aDesc->descriptorType )
  163.         err = AEResolve( aDesc, kAEIDoMinimum, &selectDesc );
  164.     else if ( typeNull != aDesc->descriptorType )
  165.         err = AEDuplicateDesc( aDesc, &selectDesc );
  166.         
  167.     if (noErr != err) goto done;
  168.     
  169.     switch (selectDesc.descriptorType)
  170.     {
  171.         case typeAEList:
  172.             err = PutPStringToDescriptor(result, "\pThis application cannot select a list of objects");
  173.             if (noErr != err) goto done;
  174.             err = errAETypeError;
  175.             break;
  176.             
  177.         case typeMyWndw:
  178.         case typeMyDocument:
  179.             err = SelectWindowDesc(&selectDesc);
  180.             break;
  181.             
  182.         case typeMyMenuItem:
  183.             err = SelectMenuItemDesc(&selectDesc);
  184.             break;
  185.             
  186.         default:
  187.             err = AECoerceDesc(&selectDesc, typeMyText, &textDesc);
  188.             if (noErr != err) goto done;
  189.             err = SelectTextDesc(&textDesc);
  190.     }
  191.     
  192. done:
  193.     (void)AEDisposeDesc( &selectDesc );
  194.     (void)AEDisposeDesc( &textDesc );
  195.     
  196.     return(err);
  197. }
  198.  
  199.  
  200. // Given a window, this routine will fill out a TextToken with details
  201. // of the window's current selection. The total text length can also be retrieved
  202. // so that the selection can be updated depending on changes.
  203.  
  204. OSErr    GetWindowSelection(WindowPtr aWindow, TextToken* resultToken, short* resultLength)
  205. {
  206.     AEDesc        propertyDesc = {typeNull, NULL},
  207.                 dataDesc = {typeNull, NULL},
  208.                 textDesc = {typeNull, NULL};
  209.     TEHandle    aTextEditHandle;
  210.     OSErr        err = noErr;
  211.     
  212.     if (! aWindow)
  213.         return(errAENoSuchObject);
  214.     
  215.     aTextEditHandle = TEHandleFromWindow(aWindow);
  216.  
  217.     resultToken->tokenWindow = aWindow;
  218.                                     // TEHandle starts counting characters from 1, not 0
  219.     resultToken->tokenOffset = (*aTextEditHandle)->selStart + 1;
  220.     resultToken->tokenLength = (*aTextEditHandle)->selEnd - (*aTextEditHandle)->selStart;
  221.     
  222.     if (resultLength)
  223.         *resultLength = (*aTextEditHandle)->teLength;
  224.     
  225.     return(err);
  226. }
  227.  
  228.  
  229. // Given the selection that was deleted/changed/?moved? and the original
  230. // selection before the operation. Also the old length of text in the
  231. // TextEdit. This routine sorts out the selection that may change
  232. // due to position of delete/change/?move?. It returns in insertLength
  233. // the length of the inserted data (not just the difference).
  234.  
  235. OSErr    UpdateSelectionToken(TextToken* anInsertToken, TextToken* aSelectionToken,
  236.                                                 short oldLength, short* insertLength)
  237. {
  238.     TextToken    updatedToken;
  239.     short        newLength,        // Lots of local variables to make
  240.                 deleteLength,    // things clearer.
  241.                 insertOffset,
  242.                 selectOffset,
  243.                 selectLength,
  244.                 numPartial;
  245.     OSErr        err;
  246.     
  247.     if (! anInsertToken->tokenWindow || ! aSelectionToken->tokenWindow)
  248.         return(errAENoSuchObject);
  249.         
  250.     updatedToken.tokenWindow = aSelectionToken->tokenWindow;
  251.     
  252.     newLength = (*TEHandleFromWindow(anInsertToken->tokenWindow))->teLength;
  253.     deleteLength = anInsertToken->tokenLength;                        // Characters deleted
  254.     
  255.     insertOffset = anInsertToken->tokenOffset;
  256.     selectOffset = aSelectionToken->tokenOffset;
  257.     selectLength = aSelectionToken->tokenLength;
  258.  
  259.     *insertLength = newLength - oldLength + deleteLength;            // Characters inserted
  260.  
  261.     switch (TokenWithinToken(aSelectionToken, anInsertToken, &numPartial))
  262.     {
  263.         case kTokenBefore:
  264.             updatedToken.tokenOffset = selectOffset + *insertLength - deleteLength;
  265.             updatedToken.tokenLength = selectLength;
  266.             break;
  267.  
  268.         case kTokenAfter:
  269.         case kTokenPartialBefore:
  270.         case kTokenPartialAfter:
  271.             updatedToken.tokenOffset = selectOffset;
  272.             updatedToken.tokenLength = selectLength;
  273.             break;
  274.             
  275.         case kTokenWithin:
  276.             updatedToken.tokenOffset = selectOffset;
  277.             updatedToken.tokenLength = selectLength + *insertLength - deleteLength;
  278.             break;
  279.     }
  280.         
  281.     err = SelectTextToken(&updatedToken);
  282.     
  283.     return(err);
  284. }
  285.